package com.laomu.web.controller;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.laomu.web.utils.URLPath;

/**
 * 工作流相关业务处理控制器
 * 
 * @ProjectName: [act-site]
 * @Package: [com.laomu.service.WorkflowService.java]
 * @ClassName: [WorkflowService]
 * @Description: [工作流程的加载、执行、信息查询等]
 * @Author: [老木]
 * @CreateDate: [2016年6月22日 下午1:48:13]
 * @UpdateUser: [老木]
 * @UpdateDate: [2016年6月22日 下午1:48:13]
 * @UpdateRemark: [说明本次修改内容]
 * @Version: [v1.0]
 */
@Controller
@RequestMapping("/act")
public class WorkflowController {
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private TaskService taskService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private ManagementService managementService;

	/**
	 * 发布流程
	 */
	@RequestMapping(value = "/deployment", method = RequestMethod.POST)
	public String deploy(@RequestParam("wfname") String wfname, @RequestParam("file") MultipartFile file) {
		try {
			repositoryService.createDeployment()// 创建发布流程对象
					.name(wfname)// 给流程命名
					.addZipInputStream(new ZipInputStream(file.getInputStream()))// 加载流程资源文件
					.deploy();// 发布流程
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "redirect:/act/procmanager";
	}

	/**
	 * 流程信息查看
	 * 
	 * @return
	 */
	@RequestMapping("/procmanager")
	public String processManager(ModelMap map) {
		// 查看流程部署信息
		List<Deployment> deployList = repositoryService.createDeploymentQuery().list();
		// 查看流程定义信息
		List<ProcessDefinition> procDeList = repositoryService.createProcessDefinitionQuery().list();
		// 保存数据
		map.put("deployList", deployList);
		map.put("procDeList", procDeList);
		return URLPath.ACT_PROC_MAG;
	}

	/**
	 * 删除流程定义
	 */
	@RequestMapping("/deletedeploy/{dpid:\\d+}/del")
	public String deleteDeployDefine(@PathVariable("dpid") String deploymentId, HttpServletResponse resp) {
		try {
			/*
			 * TODO 需要注意 在执行流程删除时，会遇到已经启动的流程删除问题 已经启动的流程删除时会丢失数据，所以需要进行流程判断
			 * 
			 * 返回数据再页面上提示用户是否有遗留数据，是否确认删除。
			 */
			repositoryService.deleteDeployment(deploymentId, true);// 级联删除
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "redirect:/act/procmanager";
	}

	/**
	 * 查看流程图
	 * 
	 * @param deploymentId
	 *            部署流程编号
	 * @param resourceName
	 *            流程图名称
	 * @return
	 */
	@RequestMapping("/procview/{deploymentId}/{resourceName}")
	public String procPngView(@PathVariable String deploymentId, @PathVariable String resourceName, ModelMap map) {
		map.put("deptId", deploymentId);
		map.put("reName", resourceName);
		return URLPath.ACT_PROC_PNG;
	}

	/**
	 * 查看流程图
	 * 
	 * @param deploymentId
	 *            部署流程编号
	 * @param resourceName
	 *            流程图名称
	 * @return
	 */
	@RequestMapping("/procpng/{deploymentId}/{resourceName}")
	public void procPng(@PathVariable String deploymentId, @PathVariable String resourceName,
			HttpServletResponse resp) {
		try {
			if (!resourceName.endsWith(".png")) {
				resourceName += ".png";
			}
			System.out.println(resourceName);
			// 读取到流程图片文件的输入流
			InputStream is = repositoryService.getResourceAsStream(deploymentId, resourceName);
			OutputStream os = resp.getOutputStream();

			resp.setContentType("image/jpeg");
			byte[] buff = new byte[1024];
			while ((is.read(buff)) != -1) {
				os.write(buff, 0, buff.length);
			}
			os.flush();

			os.close();
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 查看可申请的任务
	 * 
	 * @return
	 */
	@RequestMapping("/taskapply")
	public String taskFindApply(ModelMap map) {
		// 查看流程部署信息
		List<Deployment> deployList = repositoryService.createDeploymentQuery().list();
		
		// 查看流程部署对应的key，并将数据添加到map中
		Map<String, Deployment> taskMap = new HashMap<String, Deployment>();
		for (Deployment deployment : deployList) {
			String key = repositoryService.createProcessDefinitionQuery()
					.deploymentId(deployment.getId()).singleResult().getKey();
			taskMap.put(key, deployment);
		}
		map.put("taskMap", taskMap);
		
		return URLPath.ACT_TASK_APPLY;
	}

	/**
	 * 启动流程实例
	 * 
	 * @param deploymentId
	 *            流程部署编号
	 * @return
	 */
	@RequestMapping("/taststart/{key}")
	public String startProcessDefinition(@PathVariable("key") String key) {
		// 通过流程的key启动一个新的流程
		runtimeService.startProcessInstanceByKey(key);
		return URLPath.ACT_PROC_MAG;
	}
	
	/**
	 * 结束流程实例
	 */
	public String stopProcess() {
		return URLPath.ACT_PROC_MAG;
	}

}
